﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Sripirom.Pattern.UnitTest.Core.Domain;
using Sripirom.Pattern.UnitTest.Core.UnitOfWork;

namespace Sripirom.Pattern.UnitTest.Repository.Configuration.Repositories
{
    public abstract class XmlRepository<T, TId> : IRepository<T, TId>
        where T : BaseEntity<TId> , IAggregateRoot
    {
        private IUnitOfWork _uow;
        private XmlUnitOfWorkRepository<T, TId> _persitRepository;
        private IMapper<T> _mapper;
        public XmlRepository(IUnitOfWork uow)
        {
            _uow = uow;
            _persitRepository = new XmlUnitOfWorkRepository<T, TId>();
            Type curType = this.GetType();
            Type mapType = Type.GetType(curType.FullName.Replace("Repositories", "Mapper").Replace(curType.Name, curType.Name.Replace("Repository", "Mapper") ));
            _mapper = (IMapper<T>)System.Activator.CreateInstance(mapType);
          
        }
        public void Save(T entity)
        {
            _uow.RegisterAmended(entity, _persitRepository);
        }

        public TId Add(T entity)
        {
            _uow.RegisterNew(entity, _persitRepository);
            return entity.Id;
        }

        public void Remove(T entity)
        {
            _uow.RegisterRemoved(entity, _persitRepository);
        }

        public void Flush()
        {
            throw new NotImplementedException();
        }

        public void Evict(T entity)
        {
            throw new NotImplementedException();
        }

        public T FindBy(TId id)
        {
           return  _persitRepository.GetDocument().Descendants(typeof(T).Name)
                .Where(e => e.Attribute("Id").Value == id.ToString())
                .Select(_mapper.Selector).FirstOrDefault();
        }
     
        public IEnumerable<T> FindAll()
        {
            return _persitRepository.GetDocument().Descendants(typeof(T).Name).Select(_mapper.Selector);
        }

        public IEnumerable<T> FindAll(int index, int count)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<T> FindBy(Core.Querying.Query query)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<T> FindBy(Core.Querying.Query query, int index, int count)
        {
            throw new NotImplementedException();
        }

        public int CountAll()
        {
            throw new NotImplementedException();
        }

        public int CountBy(Core.Querying.Query query)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<T> FindFiltered(Core.Querying.Criterion criterion)
        {
            throw new NotImplementedException();
        }
    }
}
